home *** CD-ROM | disk | FTP | other *** search
/ AGA Toolkit '97 / The AGA Toolkit '97.iso / programming / gcc / gcc2.7.0 / gcc270cp.lha / gnu / lib / g++-include / std / bastring.cc next >
Encoding:
C/C++ Source or Header  |  1995-07-28  |  11.4 KB  |  524 lines

  1. // Member templates for the -*- C++ -*- string classes.
  2. // Copyright (C) 1994 Free Software Foundation
  3.  
  4. // This file is part of the GNU ANSI C++ Library.  This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 2, or (at your option)
  8. // any later version.
  9.  
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14.  
  15. // You should have received a copy of the GNU General Public License
  16. // along with this library; see the file COPYING.  If not, write to the Free
  17. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. // As a special exception, if you link this library with files
  20. // compiled with a GNU compiler to produce an executable, this does not cause
  21. // the resulting executable to be covered by the GNU General Public License.
  22. // This exception does not however invalidate any other reasons why
  23. // the executable file might be covered by the GNU General Public License.
  24.  
  25. // Written by Jason Merrill based upon the specification by Takanori Adachi
  26. // in ANSI X3J16/94-0013R2.
  27.  
  28. #include <std/stddef.h>
  29. #include <std/bastring.h>
  30.  
  31. template <class charT, class traits>
  32. inline void * __bsrep <charT, traits>::
  33. operator new (size_t s, size_t extra)
  34. {
  35.   return ::operator new (s + extra);
  36. }
  37.  
  38. template <class charT, class traits>
  39. inline size_t __bsrep <charT, traits>::
  40. #ifdef _G_ALLOC_CONTROL
  41. default_frob (size_t s)
  42. #else
  43. frob_size (size_t s)
  44. #endif
  45. {
  46.   size_t i = 16;
  47.   while (i < s) i *= 2;
  48.   return i;
  49. }
  50.  
  51. template <class charT, class traits>
  52. inline __bsrep <charT, traits> * __bsrep <charT, traits>::
  53. create (size_t extra)
  54. {
  55.   extra = frob_size (extra);
  56.   Rep *p = new (extra) Rep;
  57.   p->res = extra;
  58.   p->ref = 1;
  59.   return p;
  60. }
  61.  
  62. template <class charT, class traits>
  63. charT * __bsrep <charT, traits>::
  64. clone ()
  65. {
  66.   Rep *p = Rep::create (len);
  67.   p->copy (0, data (), len);
  68.   p->len = len;
  69.   return p->data ();
  70. }
  71.  
  72. template <class charT, class traits>
  73. inline bool __bsrep <charT, traits>::
  74. #ifdef _G_ALLOC_CONTROL
  75. default_excess (size_t s, size_t r)
  76. #else
  77. excess_slop (size_t s, size_t r)
  78. #endif
  79. {
  80.   return 2 * (s <= 16 ? 16 : s) < r;
  81. }
  82.  
  83. template <class charT, class traits>
  84. inline bool basic_string <charT, traits>::
  85. check_realloc (size_t s)
  86. {
  87.   return (rep ()->ref > 1
  88.       || s > capacity ()
  89.       || Rep::excess_slop (s, capacity ()));
  90. }
  91.  
  92. template <class charT, class traits>
  93. void basic_string <charT, traits>::
  94. alloc (size_t size, bool save)
  95. {
  96.   if (! check_realloc (size))
  97.     return;
  98.  
  99.   Rep *p = Rep::create (size);
  100.  
  101.   if (save)
  102.     {
  103.       p->copy (0, data (), length ());
  104.       p->len = length ();
  105.     }
  106.   else
  107.     p->len = 0;
  108.  
  109.   repup (p);
  110. }
  111.  
  112. template <class charT, class traits>
  113. basic_string <charT, traits>& basic_string <charT, traits>::
  114. replace (size_t pos1, size_t n1,
  115.      const basic_string& str, size_t pos2, size_t n2)
  116. {
  117.   const size_t len2 = str.length ();
  118.  
  119.   if (pos1 == 0 && n1 >= length () && pos2 == 0 && n2 >= len2)
  120.     return operator= (str);
  121.  
  122.   OUTOFRANGE (pos2 > len2);
  123.  
  124.   if (n2 > len2 - pos2)
  125.     n2 = len2 - pos2;
  126.  
  127.   return replace (pos1, n1, str.data () + pos2, n2);
  128. }
  129.  
  130. template <class charT, class traits>
  131. inline void __bsrep <charT, traits>::
  132. copy (size_t pos, const charT *s, size_t n)
  133. {
  134.   if (n)
  135.     traits::copy (data () + pos, s, n);
  136. }
  137.  
  138. template <class charT, class traits>
  139. inline void __bsrep <charT, traits>::
  140. move (size_t pos, const charT *s, size_t n)
  141. {
  142.   if (n)
  143.     traits::move (data () + pos, s, n);
  144. }
  145.  
  146. template <class charT, class traits>
  147. basic_string <charT, traits>& basic_string <charT, traits>::
  148. replace (size_t pos, size_t n1, const charT* s, size_t n2)
  149. {
  150.   const size_t len = length ();
  151.   OUTOFRANGE (pos > len);
  152.   if (n1 > len - pos)
  153.     n1 = len - pos;
  154.   LENGTHERROR (len - n1 >= npos - n2);
  155.   size_t newlen = len - n1 + n2;
  156.  
  157.   if (check_realloc (newlen))
  158.     {
  159.       Rep *p = Rep::create (newlen);
  160.       p->copy (0, data (), pos);
  161.       p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
  162.       p->copy (pos, s, n2);
  163.       repup (p);
  164.     }
  165.   else
  166.     {
  167.       rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
  168.       rep ()->copy (pos, s, n2);
  169.     }
  170.   rep ()->len = newlen;
  171.  
  172.   return *this;
  173. }
  174.  
  175. template <class charT, class traits>
  176. inline void __bsrep <charT, traits>::
  177. set (size_t pos, const charT c, size_t n)
  178. {
  179.   traits::set  (data () + pos, c, n);
  180. }
  181.  
  182. template <class charT, class traits>
  183. basic_string <charT, traits>& basic_string <charT, traits>::
  184. replace (size_t pos, size_t n1, size_t n2, charT c)
  185. {
  186.   const size_t len = length ();
  187.   OUTOFRANGE (pos > len);
  188.   if (n1 > len - pos)
  189.     n1 = len - pos;
  190.   LENGTHERROR (len - n1 >= npos - n2);
  191.   size_t newlen = len - n1 + n2;
  192.  
  193.   if (check_realloc (newlen))
  194.     {
  195.       Rep *p = Rep::create (newlen);
  196.       p->copy (0, data (), pos);
  197.       p->copy (pos + n2, data () + pos + n1, len - (pos + n1));
  198.       p->set  (pos, c, n2);
  199.       repup (p);
  200.     }
  201.   else
  202.     {
  203.       rep ()->move (pos + n2, data () + pos + n1, len - (pos + n1));
  204.       rep ()->set  (pos, c, n2);
  205.     }
  206.   rep ()->len = newlen;
  207.  
  208.   return *this;
  209. }
  210.  
  211. template <class charT, class traits>
  212. void basic_string <charT, traits>::
  213. resize (size_t n, charT c)
  214. {
  215.   LENGTHERROR (n == npos);
  216.  
  217.   if (n > length ())
  218.     append (c, n - length ());
  219.   else
  220.     remove (n);
  221. }
  222.  
  223. template <class charT, class traits>
  224. size_t basic_string <charT, traits>::
  225. copy (charT* s, size_t n, size_t pos)
  226. {
  227.   OUTOFRANGE (pos > length ());
  228.  
  229.   if (n > length () - pos)
  230.     n = length () - pos;
  231.  
  232.   traits::copy (s, data () + pos, n);
  233.   return n;
  234. }
  235.  
  236. template <class charT, class traits>
  237. size_t basic_string <charT, traits>::
  238. find (const charT* s, size_t pos, size_t n)
  239. {
  240.   size_t xpos = pos;
  241.   for (; xpos + n <= length (); ++xpos)
  242.     if (traits::eq (data () [xpos], *s)
  243.     && traits::compare (data () + xpos, s, n) == 0)
  244.       return xpos;
  245.   return npos;
  246. }
  247.  
  248. template <class charT, class traits>
  249. inline size_t basic_string <charT, traits>::
  250. _find (const charT* ptr, charT c, size_t xpos, size_t len)
  251. {
  252.   for (; xpos < len; ++xpos)
  253.     if (traits::eq (ptr [xpos], c))
  254.       return xpos;
  255.   return npos;
  256. }
  257.  
  258. template <class charT, class traits>
  259. size_t basic_string <charT, traits>::
  260. find (charT c, size_t pos)
  261. {
  262.   return _find (data (), c, pos, length ());
  263. }
  264.  
  265. template <class charT, class traits>
  266. size_t basic_string <charT, traits>::
  267. rfind (const charT* s, size_t pos, size_t n)
  268. {
  269.   size_t xpos = length () - n;
  270.   if (xpos > pos)
  271.     xpos = pos;
  272.  
  273.   for (++xpos; xpos-- > 0; )
  274.     if (traits::eq (data () [xpos], *s)
  275.     && traits::compare (data () + xpos, s, n) == 0)
  276.       return xpos;
  277.   return npos;
  278. }
  279.  
  280. template <class charT, class traits>
  281. size_t basic_string <charT, traits>::
  282. rfind (charT c, size_t pos)
  283. {
  284.   size_t xpos = length () - 1;
  285.   if (xpos > pos)
  286.     xpos = pos;
  287.  
  288.   for (++xpos; xpos-- > 0; )
  289.     if (traits::eq (data () [xpos], c))
  290.       return xpos;
  291.   return npos;
  292. }
  293.  
  294. template <class charT, class traits>
  295. size_t basic_string <charT, traits>::
  296. find_first_of (const charT* s, size_t pos, size_t n)
  297. {
  298.   size_t xpos = pos;
  299.   for (; xpos < length (); ++xpos)
  300.     if (_find (s, data () [xpos], 0, n) != npos)
  301.       return xpos;
  302.   return npos;
  303. }
  304.  
  305. template <class charT, class traits>
  306. size_t basic_string <charT, traits>::
  307. find_last_of (const charT* s, size_t pos, size_t n)
  308. {
  309.   size_t xpos = length ();
  310.   for (; xpos-- > pos; )
  311.     if (_find (s, data () [xpos], 0, n) != npos)
  312.       return xpos;
  313.   return npos;
  314. }
  315.  
  316. template <class charT, class traits>
  317. size_t basic_string <charT, traits>::
  318. find_first_not_of (const charT* s, size_t pos, size_t n)
  319. {
  320.   size_t xpos = pos;
  321.   for (; xpos < length (); ++xpos)
  322.     if (_find (s, data () [xpos], 0, n) == npos)
  323.       return xpos;
  324.   return npos;
  325. }
  326.  
  327. template <class charT, class traits>
  328. size_t basic_string <charT, traits>::
  329. find_first_not_of (charT c, size_t pos)
  330. {
  331.   size_t xpos = pos;
  332.   for (; xpos < length (); ++xpos)
  333.     if (traits::ne (data () [xpos], c))
  334.       return xpos;
  335.   return npos;
  336. }
  337.  
  338. template <class charT, class traits>
  339. size_t basic_string <charT, traits>::
  340. find_last_not_of (const charT* s, size_t pos, size_t n)
  341. {
  342.   size_t xpos = length ();
  343.   for (; xpos-- > pos; )
  344.     if (_find (s, data () [xpos], 0, n) == npos)
  345.       return xpos;
  346.   return npos;
  347. }
  348.  
  349. template <class charT, class traits>
  350. size_t basic_string <charT, traits>::
  351. find_last_not_of (charT c, size_t pos)
  352. {
  353.   size_t xpos = length ();
  354.   for (; xpos-- > pos; )
  355.     if (traits::ne (data () [xpos], c))
  356.       return xpos;
  357.   return npos;
  358. }
  359.  
  360. template <class charT, class traits>
  361. int basic_string <charT, traits>::
  362. compare (const basic_string& str, size_t pos, size_t n) const
  363. {
  364.   OUTOFRANGE (pos > length ());
  365.  
  366.   size_t rlen = length () - pos;
  367.   if (rlen > n)
  368.     rlen = n;
  369.   if (rlen > str.length ())
  370.     rlen = str.length ();
  371.   int r = traits::compare (data () + pos, str.data (), rlen);
  372.   if (r != 0)
  373.     return r;
  374.   if (rlen == n)
  375.     return 0;
  376.   return (length () - pos) - str.length ();
  377. }
  378.  
  379. template <class charT, class traits>
  380. int basic_string <charT, traits>::
  381. compare (const charT* s, size_t pos, size_t n) const
  382. {
  383.   OUTOFRANGE (pos > length ());
  384.  
  385.   size_t rlen = length () - pos;
  386.   if (rlen > n)
  387.     rlen = n;
  388.   int r = traits::compare (data () + pos, s, rlen);
  389.   if (r != 0)
  390.     return r;
  391.   return (length () - pos) - n;
  392. }
  393.  
  394. #include <iostream.h>
  395.  
  396. // This function is complex to avoid unnecessary shrinking of the string
  397. // argument.  Does this actually buy us anything?
  398.  
  399. template <class charT, class traits>
  400. istream &
  401. operator>> (istream &is, basic_string <charT, traits> &s)
  402. {
  403.   int w = is.width (0);
  404.   if (is.ipfx0 ())
  405.     {
  406.       register size_t len = 0;
  407.       const size_t oldalloc = s.capacity ();
  408.       register streambuf *sb = is.rdbuf ();
  409.  
  410.       while (1)
  411.     {
  412.       if (len == oldalloc)
  413.         goto next;
  414.  
  415.       int ch = sb->sbumpc ();
  416.       if (ch == EOF)
  417.         {
  418.           is.setstate (ios::eofbit);
  419.           break;
  420.         }
  421.       else if (traits::is_del (ch))
  422.         {
  423.           sb->sungetc ();
  424.           break;
  425.         }
  426.       s[len++] = ch;
  427.       if (--w == 1)
  428.         break;
  429.     }
  430.       s.resize (len);
  431.       goto done;
  432.  
  433.     next:
  434.       while (1)
  435.     {
  436.       int ch = sb->sbumpc ();
  437.       if (ch == EOF)
  438.         {
  439.           is.setstate (ios::eofbit);
  440.           break;
  441.         }
  442.       else if (traits::is_del (ch))
  443.         {
  444.           sb->sungetc ();
  445.           break;
  446.         }
  447.       s += ch;
  448.       if (--w == 1)
  449.         break;
  450.     }
  451.     }
  452.  done:
  453.   is.isfx ();
  454.   if (s.length () == 0)
  455.     is.setstate (ios::failbit);
  456.  
  457.   return is;
  458. }
  459.  
  460. template <class charT, class traits>
  461. ostream &
  462. operator<< (ostream &o, const basic_string <charT, traits>& s)
  463. {
  464.   return o.write (s.data (), s.length ());
  465. }
  466.  
  467. template <class charT, class traits>
  468. istream&
  469. getline (istream &is, basic_string <charT, traits>& s, charT delim)
  470. {
  471.   if (is.ipfx1 ())
  472.     {
  473.       register size_t len = 0;
  474.       const size_t oldalloc = s.capacity ();
  475.       streambuf *sb = is.rdbuf ();
  476.  
  477.       while (1)
  478.     {
  479.       if (len == oldalloc)
  480.         goto next;
  481.  
  482.       int ch = sb->sbumpc ();
  483.       if (ch == EOF)
  484.         {
  485.           is.setstate (ios::eofbit);
  486.           break;
  487.         }
  488.       else if (ch == delim)
  489.         break;
  490.  
  491.       s[len++] = ch;
  492.     }
  493.       s.resize (len);
  494.       goto done;
  495.  
  496.     next:
  497.       while (1)
  498.     {
  499.       int ch = sb->sbumpc ();
  500.       if (ch == EOF)
  501.         {
  502.           is.setstate (ios::eofbit);
  503.           break;
  504.         }
  505.       else if (ch == delim)
  506.         break;
  507.  
  508.       s += ch;
  509.  
  510.       if (s.length () == s.npos - 1)
  511.         {
  512.           is.setstate (ios::failbit);
  513.           break;
  514.         }
  515.     }
  516.     }
  517.  done:
  518.   is.isfx ();
  519.   if (s.length () == 0)
  520.     is.setstate (ios::failbit);
  521.  
  522.   return is;
  523. }
  524.